/**
 * $Id: CalcNumber.java 13 2006-10-25 18:36:07Z masamic.japan $
 */
package net.masamic.utils.math;

/**
 * @author masamic
 *
 */
public class CalcNumber {

	/**
	 * 
	 * @param arg1
	 * @param arg2
	 * @throws Exception
	 */
	protected static void checkParam(Number arg1, Number arg2) throws Exception {

		if (arg1 == null || arg2 == null) {
			throw new NullPointerException();
		}

		if (!arg1.getClass().equals(arg2.getClass())) {
			throw new ArithmeticException("Each Argument is not same class.");
		}

	}
	
	/**
	 * 
	 * @param arg1
	 * @param arg2
	 * @return
	 * @throws Exception
	 */
	public static Number add(Number arg1, Number arg2) throws Exception {

		checkParam(arg1, arg2);
		
		Number ret = null;
		
		if (arg1 instanceof Integer) {
			ret = Integer.valueOf(arg1.intValue() + arg2.intValue());
		} else if (arg1 instanceof Short) {
			ret = Short.valueOf((short)(arg1.shortValue() + arg2.shortValue()));
		} else if (arg1 instanceof Long) {
			ret = Long.valueOf(arg1.longValue() + arg2.longValue());
		} else if (arg1 instanceof Float) {
			ret = Float.valueOf((float)(arg1.floatValue() + arg2.floatValue()));
		} else if (arg1 instanceof Double) {
			ret = Double.valueOf(arg1.doubleValue() + arg2.doubleValue());
		} else {
			throw new ArithmeticException("Unsupported Number Object.");
		}
		
		return ret;
	}

	/**
	 * 
	 * @param arg1
	 * @param arg2
	 * @return
	 * @throws Exception
	 */
	public static Number sub(Number arg1, Number arg2) throws Exception {

		checkParam(arg1, arg2);
		
		Number ret = null;
		
		if (arg1 instanceof Integer) {
			ret = Integer.valueOf(arg1.intValue() - arg2.intValue());
		} else if (arg1 instanceof Short) {
			ret = Short.valueOf((short)(arg1.shortValue() - arg2.shortValue()));
		} else if (arg1 instanceof Long) {
			ret = Long.valueOf(arg1.longValue() - arg2.longValue());
		} else if (arg1 instanceof Float) {
			ret = Float.valueOf((float)(arg1.floatValue() - arg2.floatValue()));
		} else if (arg1 instanceof Double) {
			ret = Double.valueOf(arg1.doubleValue() - arg2.doubleValue());
		} else {
			throw new ArithmeticException("Unsupported Number Object.");
		}
		
		return ret;
	}

	/**
	 * 
	 * @param arg1
	 * @param arg2
	 * @return
	 * @throws Exception
	 */
	public static Number multiply(Number arg1, Number arg2) throws Exception {

		checkParam(arg1, arg2);
		
		Number ret = null;
		
		if (arg1 instanceof Integer) {
			ret = Integer.valueOf(arg1.intValue() * arg2.intValue());
		} else if (arg1 instanceof Short) {
			ret = Short.valueOf((short)(arg1.shortValue() * arg2.shortValue()));
		} else if (arg1 instanceof Long) {
			ret = Long.valueOf(arg1.longValue() * arg2.longValue());
		} else if (arg1 instanceof Float) {
			ret = Float.valueOf((float)(arg1.floatValue() * arg2.floatValue()));
		} else if (arg1 instanceof Double) {
			ret = Double.valueOf(arg1.doubleValue() * arg2.doubleValue());
		} else {
			throw new ArithmeticException("Unsupported Number Object.");
		}
		
		return ret;
	}

	/**
	 * 
	 * @param arg1
	 * @param arg2
	 * @return
	 * @throws Exception
	 */
	public static Number divide(Number arg1, Number arg2) throws Exception {

		checkParam(arg1, arg2);

		if (arg2.doubleValue() == 0.0) {
			throw new ArithmeticException("Divided by zero.");
		}
		
		Number ret = null;
		
		if (arg1 instanceof Integer) {
			ret = Integer.valueOf(arg1.intValue() / arg2.intValue());
		} else if (arg1 instanceof Short) {
			ret = Short.valueOf((short)(arg1.shortValue() / arg2.shortValue()));
		} else if (arg1 instanceof Long) {
			ret = Long.valueOf(arg1.longValue() / arg2.longValue());
		} else if (arg1 instanceof Float) {
			ret = Float.valueOf((float)(arg1.floatValue() / arg2.floatValue()));
		} else if (arg1 instanceof Double) {
			ret = Double.valueOf(arg1.doubleValue() / arg2.doubleValue());
		} else {
			throw new ArithmeticException("Unsupported Number Object.");
		}
		
		return ret;
	}

}
